// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

<template>
  <a-form class="form" layout="vertical" v-ctrl-enter="handleKeyboardSubmit">
    <a-alert class="top-spaced" type="warning">
      <template #message>
        <span v-html="$t('message.migrate.volume', { volume: resource.name, storage: resource.storage })" />
      </template>
    </a-alert>
    <a-form-item style="margin-top: 10px;">
      <template #label>
        <tooltip-label :title="$t('label.storagepool')" :tooltip="$t('message.migrate.volume.tooltip')"/>
      </template>
      <storage-pool-select-view
        ref="storagePoolSelection"
        :resource="resource"
        :suitabilityEnabled="true"
        @change="fetchDiskOfferings"
        @storagePoolsUpdated="handleStoragePoolsChange"
        @select="handleStoragePoolSelect" />
    </a-form-item>
    <div class="top-spaced" v-if="storagePools.length > 0">
      <div v-if="resource.virtualmachineid">
        <p class="modal-form__label" @click="replaceDiskOffering = !replaceDiskOffering" style="cursor:pointer;">
          {{ $t('label.usenewdiskoffering') }}
        </p>
        <a-checkbox v-model:checked="replaceDiskOffering" />

        <template v-if="replaceDiskOffering">
          <p class="modal-form__label">{{ $t('label.newdiskoffering') }}</p>
          <a-select
            :loading="diskOfferingLoading"
            v-model:value="selectedDiskOffering"
            style="width: 100%;"
            showSearch
            optionFilterProp="label"
            :filterOption="(input, option) => {
              return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
            }" >
            <a-select-option v-for="(diskOffering, index) in diskOfferings" :value="diskOffering.id" :key="index" :label="diskOffering.displaytext">
              {{ diskOffering.displaytext }}
            </a-select-option>
          </a-select>
        </template>
      </div>
    </div>

    <a-divider />

    <div class="actions">
      <a-button @click="closeModal">{{ $t('label.cancel') }}</a-button>
      <a-button type="primary" ref="submit" :disabled="!selectedStoragePool" @click="submitForm">{{ $t('label.ok') }}</a-button>
    </div>
  </a-form>
</template>

<script>
import { api } from '@/api'
import TooltipLabel from '@/components/widgets/TooltipLabel'
import StoragePoolSelectView from '@/components/view/StoragePoolSelectView'

export default {
  name: 'MigrateVolume',
  components: {
    StoragePoolSelectView,
    TooltipLabel
  },
  props: {
    resource: {
      type: Object,
      required: true
    }
  },
  inject: ['parentFetchData'],
  data () {
    return {
      storagePools: [],
      selectedStoragePool: null,
      diskOfferings: [],
      diskOfferingLoading: false,
      replaceDiskOffering: false,
      selectedDiskOffering: null,
      isSubmitted: false
    }
  },
  watch: {
    replaceDiskOffering (newValue) {
      if (newValue) {
        this.fetchDiskOfferings()
      }
    }
  },
  created () {
    this.fetchStoragePools()
  },
  methods: {
    fetchStoragePools () {
      if (this.resource.virtualmachineid) {
        api('findStoragePoolsForMigration', {
          id: this.resource.id
        }).then(response => {
          this.storagePools = response.findstoragepoolsformigrationresponse.storagepool || []
          if (Array.isArray(this.storagePools) && this.storagePools.length) {
            this.selectedStoragePool = this.storagePools[0].id || ''
            this.fetchDiskOfferings()
          }
        }).catch(error => {
          this.$notifyError(error)
          this.closeModal()
        })
      } else {
        api('listStoragePools', {
          zoneid: this.resource.zoneid
        }).then(response => {
          this.storagePools = response.liststoragepoolsresponse.storagepool || []
          this.storagePools = this.storagePools.filter(pool => { return pool.id !== this.resource.storageid })
          if (Array.isArray(this.storagePools) && this.storagePools.length) {
            this.selectedStoragePool = this.storagePools[0].id || ''
            this.fetchDiskOfferings()
          }
        }).catch(error => {
          this.$notifyError(error)
          this.closeModal()
        })
      }
    },
    fetchDiskOfferings () {
      this.diskOfferingLoading = true
      if (this.resource.virtualmachineid) {
        api('listDiskOfferings', {
          storageid: this.selectedStoragePool.id,
          listall: true
        }).then(response => {
          this.diskOfferings = response.listdiskofferingsresponse.diskoffering
          if (this.diskOfferings) {
            this.selectedDiskOffering = this.diskOfferings[0].id
          }
        }).catch(error => {
          this.$notifyError(error)
          this.closeModal()
        }).finally(() => {
          this.diskOfferingLoading = false
          if (this.diskOfferings.length > 0) {
            this.selectedDiskOffering = this.diskOfferings[0].id
          }
        })
      }
    },
    handleStoragePoolsChange (storagePools) {
      this.storagePools = storagePools
    },
    handleStoragePoolSelect (storagePool) {
      this.selectedStoragePool = storagePool
    },
    handleKeyboardSubmit () {
      if (!this.selectedStoragePool) {
        return
      }
      this.submitForm()
    },
    closeModal () {
      this.$emit('close-action')
    },
    submitForm () {
      if (this.isSubmitted) return
      if (this.storagePools.length === 0) {
        this.closeModal()
        return
      }
      this.isSubmitted = true
      var params = {
        livemigrate: this.resource.vmstate === 'Running',
        storageid: this.selectedStoragePool.id,
        volumeid: this.resource.id
      }
      if (this.replaceDiskOffering) {
        params.newdiskofferingid = this.selectedDiskOffering
      }
      api('migrateVolume', params).then(response => {
        this.$pollJob({
          title: this.$t('label.migrate.volume'),
          description: this.resource.id,
          jobId: response.migratevolumeresponse.jobid,
          successMessage: this.$t('message.success.migrate.volume'),
          errorMessage: this.$t('message.migrate.volume.failed'),
          errorMethod: () => {
            this.isSubmitted = false
          },
          loadingMessage: this.$t('message.migrate.volume.processing'),
          catchMessage: this.$t('error.fetching.async.job.result'),
          catchMethod: () => {
            this.parentFetchData()
            this.isSubmitted = false
          }
        })
        this.closeModal()
      }).catch(error => {
        this.$notifyError(error)
        this.isSubmitted = false
      })
    }
  }
}
</script>

<style scoped lang="scss">
  .form {
    width: 80vw;

    @media (min-width: 900px) {
      width: 850px;
    }
  }

  .top-spaced {
    margin-top: 20px;
  }

  .actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 20px;

    button {
      &:not(:last-child) {
        margin-right: 10px;
      }
    }
  }
</style>
